home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume7 / nethack3 / patch8t < prev    next >
Encoding:
Internet Message Format  |  1990-06-08  |  59.5 KB

  1. Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v10i038:  NetHack3 -  display oriented dungeons & dragons (Ver. 3.0), Patch8t
  5. Message-ID: <5746@tekred.CNA.TEK.COM>
  6. Date: 5 Jun 90 18:02:26 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2247
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 10, Issue 38
  13. Archive-name: NetHack3/Patch8t
  14. Patch-To: NetHack3: Volume 7, Issue 56-93
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 20 (of 24)."
  25. # Contents:  Install.mac do_patch8.sh others/ovlmgr.asm
  26. #   vms/vmsmisc.c
  27. # Wrapped by billr@saab on Mon Jun  4 15:40:30 1990
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. echo shar: Extracting \"'Install.mac'\" \(14959 characters\)
  30. sed "s/^X//" >'Install.mac' <<'END_OF_FILE'
  31. X                Macintosh NetHack 3.0 Installation Guide
  32. X                ========================================
  33. X                last modification date: May 28th, 1990
  34. X
  35. X(Original credit for porting NetHack 3.0 to the Macintosh goes to Johnny
  36. XLee and Michael Sokolov. David Hairston, Kevin Sitze, Andy Swanson, Jon
  37. XWatte and Tom West helped polish this port in later versions.)
  38. X
  39. X0.  Some notes before getting started. These instructions work for the
  40. X    Think C 4.0 compiler. Other Macintosh compilers should be okay (i.e.
  41. X    Lightspeed C 3.0 and Manx Aztec C), however some work may be needed
  42. X    to complete the build. For other compilers you can use the various
  43. X    Makefiles and your compiler errors as guides in building the game.
  44. X
  45. X    You should maintain the file/folder structure given in the distri-
  46. X    bution file "Files". These notes assume the file structure listed
  47. X    below. Place the "top" folder appropriately in your compilers
  48. X    development folder. You'll need ~6M disk space for development.
  49. X    top:
  50. X      Files
  51. X      Install.mac
  52. X      Makefile.top
  53. X      auxil:    (... all files) {auxiliary support files}
  54. X      include:  (... all files) {header files}
  55. X      mac:      (... all files) {Macintosh specific files}
  56. X      others:   (pcconf.c, pcmain.c, pctty.c & random.c only)
  57. X      src:      (... all files) {generic source files}
  58. X
  59. X    Now is a good time to decode the *.hqx files (mac folder), creating
  60. X    3 Think C 4.0 project files and 2 associated resource files. You may
  61. X    use BinHex 4.0 or Stuffit 1.5.1 for this. These 5 files (*.proj and
  62. X    *.rsrc) should be moved from the mac folder into the "top" folder.
  63. X
  64. X    Use your favorite text editor to create an empty file of type "TEXT".
  65. X    This file should be called "news" and should be placed in the auxil
  66. X    folder. If you decide to use the news feature of NetHack you can
  67. X    write an appropriate starting message in this file.
  68. X
  69. X    Create a folder called "dungeon" in your "top" folder. This is where
  70. X    we'll copy the final files needed to run NetHack.
  71. X
  72. X    Finally, you should have no problem compiling the NetHack sources, as
  73. X    distributed. However, if you intend to make changes to the sources you
  74. X    should consider backing up your disk to prevent problems. Also, trash
  75. X    (or perhaps alter the creator signature of) your old versions of NetHack
  76. X    3.0 to avoid conflicts.
  77. X
  78. X    Okay, let's get started. We're going to make 3 applications, in order:
  79. X    (1) makedefs, to create customized files for the game, (2) spec_lev,
  80. X    to create special challenging maze-like levels and (3) nethack! The
  81. X    full build from scratch takes less than an hour using Think C 4.0 .
  82. X
  83. X1a. Make sure all the NetHack files are in the appropriate folder structure.
  84. X    You should have a top folder with subfolders auxil, include, mac, others,
  85. X    and src. The provided Think C 4.0 projects assume this structure (as do
  86. X    the provided Makefiles).
  87. X
  88. X1b. If your compiler doesn't handle subfolders you'll need to place all the
  89. X    inter-related source (*.c) and header (*.h) files in a common folder. It
  90. X    may require some work but you should be able to follow the dependencies
  91. X    in the Makefiles to build the game.
  92. X
  93. X2.  If your compiler utilizes the make/Makefile facilities, you'll need to
  94. X    remove the tags from the Makefiles (auxil, src and top) and edit them
  95. X    appropriately. The Makefiles are not needed if you can use the provided
  96. X    Think C 4.0 project files.
  97. X
  98. X3.  Edit the config.h file making the following changes to configure it
  99. X    properly for the Macintosh:
  100. X
  101. X    Section 1. OS Selection.
  102. X    Comment out: #define UNIX
  103. X    Uncomment  : #define MACOS (bottom of the ifdef __MSDOS__ else clause).
  104. X
  105. X    Within the #ifdef MACOS segment configure the #define's to choose your
  106. X    compiler. The default is to use THINKC4. For now, skip the other
  107. X    #define's there. Note that if your compiler is LSC or AZTEC, the KR1ED
  108. X    compiler directive is automatically defined for you. This directive
  109. X    allows these compilers to use the defined() construct. Additionally,
  110. X    for the LSC a/o AZTEC compilers you'll also need to add the line:
  111. X    #define defined(x) (-x-1 != -1)
  112. X    before the first occurrence of #if defined(x) in random.c and mon.c!
  113. X
  114. X    Section 2. Some global parameters and filenames.
  115. X    For THINKC4 define the WIZARD name. A good choice is "debug" since
  116. X    that is the purpose of this option. For LSC or AZTEC define the
  117. X    WIZARD_NAME appropriately. This is the name that needs to appear in
  118. X    your "NetHack Prefs" file (system folder) in order to use Wizard
  119. X    (Debug) mode.
  120. X
  121. X    Comment out: #define LOGFILE "logfile"
  122. X
  123. X    Section 3. Definitions that may vary with system type.
  124. X    The defaults are all okay here for THINKC4, LSC and AZTEC.
  125. X     
  126. X    Section 4. THE FUN STUFF!!!
  127. X    uncomment:   #define SCORE_ON_BOTL  (This is optional. It will allow
  128. X    you to see your current score on the bottom line during play.)
  129. X    The rest of the #define's default to configuring a "full-featured"
  130. X    NetHack game.
  131. X
  132. X    Save the config.h file.
  133. X
  134. X    If you intend to customize the game you will want to look at the files
  135. X    macconf.h and system.h. This typically isn't needed for simply building
  136. X    the game.
  137. X
  138. X4.  Now we're going to build the makedefs application. This application
  139. X    depends on various header files and the source files:
  140. X    alloc.c  macfile.c  makedefs.c  monst.c  objects.c  & panic.c .
  141. X    If necessary look at the Makefile(.src) to determine the dependencies.
  142. X    You'll need to load the libraries appropriate for your compiler. THINKC4
  143. X    users can simply open the "makedefs.proj" file.
  144. X
  145. X    Re-edit the config.h file! Go to the #ifdef MACOS segment in section 1.
  146. X    Comment out: #define CUSTOM_IO .
  147. X    Uncomment  : #define MAKEDEFS_C .
  148. X
  149. X    Close the config.h file, saving the changes.
  150. X
  151. X    Build the makedefs application. The Think C 4.0 project uses resources
  152. X    from the "makedefs.proj.rsrc" file. Save the application in the "top"
  153. X    folder. Close the project. Run the makedefs application, sequentially
  154. X    choosing all seven options. This will require re-launching each time.
  155. X    You've now created additional auxiliary files for the game and added
  156. X    icons and signatures to these 12 files (auxil folder): cmdhelp, data,
  157. X    help, hh, history, license, MacHelp, news, opthelp, oracles, record,
  158. X    and rumors. These files can now be copied into the dungeon folder.
  159. X
  160. X    If you decide to change features in the game, remember to always
  161. X    rebuild makedefs first to setup the needed data structures and so on
  162. X    for the game.
  163. X
  164. X5.  Next, we're going to build the spec_lev application. This application
  165. X    depends on various header files and the source files:
  166. X    alloc.c  lev_comp.c  lev_lex.c  lev_main.c  macfile.c  monst.c
  167. X    objects.c  & panic.c
  168. X    If you copied the alternate file lev_lex.c in the "others" folder, you
  169. X    should remove (or rename) it to avoid problems with src:lev_lex.c. The
  170. X    dependencies here are similar to the ones for the makedefs project.
  171. X    Again, if necessary, refer to the Makefile(.src) for help. You should
  172. X    need the same libraries for this application as you did for makedefs.
  173. X    THINKC4 users can simply open the "spec_lev.proj" file.
  174. X
  175. X    The changes needed to build this application are more complicated than
  176. X    before, however the checklist provided below should cover all the bases.
  177. X
  178. X   *Edit config.h (Section 1. within the #ifdef MACOS segment)
  179. X    Comment out: #define MAKEDEFS_C
  180. X    Comment out: #define NEED_VARARGS  {more on pre-compiled headers later}
  181. X    Save the changes to config.h and close the file.
  182. X
  183. X   *Edit lev_lex.c. These changes will appear sequentially:
  184. X    Find                                    Replace with
  185. X    {... near the beginning ...}
  186. X    int yyleng; extern char yytext[];       int yyleng; extern char *yytext;
  187. X    int yymorfg;                            int yymorfg;
  188. X    extern char *yysptr, yysbuf[];          extern char *yysptr, *yysbuf;
  189. X    int yytchar;                            int yytchar;
  190. X    File *yyin ={stdin}, *yyout ={stdout};  File *yyin =stdin, *yyout =stdout;
  191. X    {... near the end ...}
  192. X    {... If you're using LSC or THINKC4 comment out: ...}
  193. X    {... #define NLSTATE yyprevious=YYNEWLINE ...}
  194. X    char yytext[YYLMAX];                    char *yytext;
  195. X    {... Skip a line ...}
  196. X    char yysbuf[YYLMAX];                    char *yysbuf;
  197. X    char *yysptr = yysbuf;                  char *yysptr;
  198. X    Save the changes to lev_lex.c and close the file.
  199. X
  200. X   *Edit lev_comp.c near the middle of the file.
  201. X    Find                                    Replace with
  202. X    #endif not lint                         #endif /* not lint */
  203. X    Save the change to lev_comp.c and close the file.
  204. X
  205. X   *Edit lev_main.c near the beginning of the file.
  206. X    Uncomment:   #include "hack.h"
  207. X    Save the change to lev_main.c and close the file.
  208. X
  209. X    Build the spec_lev application and save it into the "top" folder.
  210. X    Close the spec_lev project. Now run the spec_lev application, it
  211. X    will show you what file it is currently working on and create the
  212. X    5 special levels: castle, endgame, tower1, tower2 and tower3 in
  213. X    the top folder. These 5 files should be moved into the dungeon
  214. X    folder.
  215. X
  216. X    If you're really motivated and want to create customized special
  217. X    levels it should be possible to modify the special level compiler
  218. X    to accomodate your efforts. You'll also want to edit the "descrip[]"
  219. X    and "argc" variables, appropriately in lev_main.c within the ifdef
  220. X    MACOS segments, to get the compiler to recognize your custom levels.
  221. X    This is not trivial! You probably won't bother (no one has)!
  222. X
  223. X    If you decide to change features in the game, remember to rebuild
  224. X    the special levels compiler to reflect those changes and also
  225. X    recreate the special levels.
  226. X
  227. X6.  This is what you've been waiting for! Now we're going to build the
  228. X    game. The file "Segments.mac" shows the source dependencies for this
  229. X    application and suggests a workable scheme for creating properly sized
  230. X    segments. THINKC4 users can simply open the "nethack.proj" file, other
  231. X    users should build segments according to "Segments.mac" and also add
  232. X    in the appropriate libraries.
  233. X
  234. X    Follow the checklist below which indicates the changes needed to build
  235. X    the game.
  236. X
  237. X   *Edit topten.c near the beginning and set the following values:
  238. X    #define POINTSMIN 51
  239. X    #define ENTRYMAX 50
  240. X    comment out: #define PERS_IS_UID
  241. X    This will keep the size of the record file reasonable. Save your
  242. X    changes and close topten.c .
  243. X
  244. X   *Edit config.h within the #ifdef MACOS segment:
  245. X    uncomment:   #define CUSTOM_IO
  246. X    uncomment:   #define NEED_VARARGS
  247. X    Save your changes to config.h and close the file.
  248. X
  249. X    Since we're going to use pre-compiled headers in our THINKC4 project
  250. X    a minor lexical change needs to be made to several files. The
  251. X    affected files are:
  252. X    alloc.c     apply.c     end.c       extralev.c  mkroom.c    monmove.c
  253. X    pager.c     pctty.c     pri.c       priest.c    save.c      shk.c
  254. X    sounds.c    termcap.c   topl.c      topten.c
  255. X    In these files we'll need to comment out the #define's that appear
  256. X    before the first #include compiler directive. Usually this only
  257. X    involves a single #define (end.c, monmove.c and topten.c are exceptions).
  258. X    This can be done fairly easily using the regular expression search
  259. X    feature of the "Find" command. Assuming that all files are in the project
  260. X    invoke the "Find" command from the "Search" menu. Enter these fields:
  261. X    Search For:                            Replace with:
  262. X    ^\(#.*pre-compiled headers \*\/\)      /*\1
  263. X    Check the "Grep" and "Multi-File Search" check boxes (you'll be
  264. X    looking in all .c files) then click the "Don't Find" button.
  265. X    Now repeat this sequence:
  266. X    1) Select "Find in Next File" from the "Search" menu.
  267. X    2) When it finally makes a match, Select "Replace All".
  268. X    3) Click the "Okay" button in the ensuing alert and go back to (1),
  269. X    until there are no more matches. Save the changes to these files
  270. X    and close them all (you may consider doing 6 at a time if having
  271. X    too many open windows is a problem).
  272. X
  273. X    Copy the files hack.h and config.h to oldhack.h. and oldconfig.h,
  274. X    respectively. You'll need the old*.h files (properly renamed) if you
  275. X    make changes to the game and need to rebuild the makedefs and spec_lev
  276. X    applications. Trash the hack.h file and "Open" the "oldhack.h" file
  277. X    for editing. Select "Precompile ..." fom the "Source menu and save the
  278. X    result as "hack.h". Close the oldhack.h file. Now trash the "config.h"
  279. X    file and "Open" the "oldconfig.h" file for editing. Again select
  280. X    "Precompile ..." and save the result as "config.h". Close the file
  281. X    oldconfig.h . Make sure that you aren't auto-including "MacHeaders"
  282. X    by selecting the "Options ..." entry from the "Edit" menu. Click the
  283. X    "Code Generation" radio button and make sure that "<MacHeaders>" is
  284. X    not checked.
  285. X
  286. X    Build the application, this make take a few minutes. Save the game
  287. X    into the dungeon folder. Close the nethack project and you're ready
  288. X    to play the game (I hope all went well).
  289. X
  290. XSpecial Note: If you are attempting to build Nethack 3.0 on a 1M Macintosh
  291. X    using Think C 4.0, then memory may be a problem. It is suggested that
  292. X    you turn off debugging info for monst.c and objects.c . Also, if for
  293. X    some reason, compilation stops in the segment containing these two
  294. X    files after they have been compiled, then you should drag these two
  295. X    files into a separate segment, finish compiling the files of the
  296. X    original segment and then restore these two files to the original
  297. X    segment. Alternatively, you may decide to "Kompile" monst.c and
  298. X    objects.c separately while preserving the given segmentation scheme.
  299. X
  300. X7.  Cleanup. It's a good idea to always rebuild the makedefs and spec_lev
  301. X    applications from scratch. Therefore you can trash these applications
  302. X    and also remove the objects from their respective projects (Think C
  303. X    compilers) to conserve disk space. The same can be done for your
  304. X    nethack project. Consider the changes outlined above and undo them
  305. X    as needed to rebuild the project, if you decide to modify the game.
  306. X    If you're satisfied with the "full-featured" game you can trash all
  307. X    the files for a real saving!
  308. X
  309. XNotes:
  310. X1.  You should trash bones and save files from previous versions since
  311. X    they will not work with this version. Record files will work but
  312. X    notice that new scores will have a different format. It is easiest
  313. X    to just start fresh with a new scoreboard (record file).
  314. X
  315. X2.  If you can afford the RAM space you might consider giving the game
  316. X    a 1M partition in Multifinder instead of the default 750k.
  317. X
  318. X    We, the members of the Macintosh NetHack Development Team, hope you
  319. X    enjoy the game. We've worked hard at porting and polishing it to
  320. X    make it behave in the Macintosh way!
  321. END_OF_FILE
  322. if test 14959 -ne `wc -c <'Install.mac'`; then
  323.     echo shar: \"'Install.mac'\" unpacked with wrong size!
  324. fi
  325. # end of 'Install.mac'
  326. echo shar: Extracting \"'do_patch8.sh'\" \(330 characters\)
  327. sed "s/^X//" >'do_patch8.sh' <<'END_OF_FILE'
  328. X#! /bin/sh
  329. X# script to call patch to apply diff files
  330. X# make sure all of the patch files (and this file) are in your top level
  331. X# NetHack directory
  332. X#
  333. Xecho "deleting outdated files"
  334. Xrm -f mac/NH3.proj.hqx mac/NH3.rsrc.hqx vms/Install.com
  335. Xecho "applying patch8"
  336. Xcat patch8.?? | patch -p
  337. Xecho "all patches applied, check for rejects"
  338. END_OF_FILE
  339. if test 330 -ne `wc -c <'do_patch8.sh'`; then
  340.     echo shar: \"'do_patch8.sh'\" unpacked with wrong size!
  341. fi
  342. chmod +x 'do_patch8.sh'
  343. # end of 'do_patch8.sh'
  344. echo shar: Extracting \"'others/ovlmgr.asm'\" \(40486 characters\)
  345. sed "s/^X//" >'others/ovlmgr.asm' <<'END_OF_FILE'
  346. X;    SCCS Id: @(#)ovlmgr.asm         90/05/27
  347. X;  Copyright (c) 1989, 1990 Pierre Martineau and Stephen Spackman. All Rights Reserved.
  348. X;  This product may be freely redistributed.  See NetHack license for details.
  349. X
  350. XVERSION     EQU    3081h
  351. X
  352. X        PAGE    57,132
  353. X        TITLE    'DOS Overlay Manager for MSC 5.1+'
  354. X        SUBTTL    'Copyright (c) 1989, 1990 Pierre Martineau and Stephen Spackman. All Rights Reserved.'
  355. X
  356. X; acknowledgements:   - Many thanks to Norm Meluch for his invaluable help
  357. X;              - No thanks to Microsoft
  358. X;              - alltrsidsctysti!!!
  359. X;              - izchak and friends for impetus
  360. X;              - us for brilliance
  361. X;              - coffee for speed
  362. X;              - others as necessary
  363. X
  364. X; assumptions:          - all registers are preserved including flags
  365. X;              - the stack is preserved
  366. X;              - re-entrancy is not required
  367. X
  368. XDOSALLOC    EQU    48h            ; memory allocation
  369. XDOSFREE     EQU    49h            ; free allocated memory
  370. XDOSREALLOC    EQU    4ah            ; modify memory block
  371. XDOSREAD     EQU    3fh            ; read bytes from handle
  372. XDOSSEEK     EQU    42h            ; logical handle seek
  373. XDOSOPEN     EQU    3dh            ; open handle
  374. XDOSCLOSE    EQU    3eh            ; close handle
  375. XDOSEXEC     EQU    4bh            ; exec child process
  376. XDOSPUTC     EQU    02h            ; print a char
  377. XDOSVERSION    EQU    30h            ; get version number
  378. XDOSGETVEC    EQU    35h            ; get interrupt vector
  379. XDOS        EQU    21h            ; Dos interrupt #
  380. XPRINT        EQU    09h            ; print string
  381. XTERMINATE    EQU    4ch            ; terminate process
  382. XEMM        EQU    67h            ; EMM handler int vector
  383. XEMMSTATUS    EQU    40h            ; get EMM status
  384. XEMMFRAME    EQU    41h            ; get EMM page frame
  385. XEMMTOTALS    EQU    42h            ; get EMM pages available
  386. XEMMALLOC    EQU    43h            ; allocate EMM pages
  387. XEMMMAP        EQU    44h            ; map EMM pages
  388. XEMMFREE     EQU    45h            ; free EMM pages
  389. XCR        EQU    0dh
  390. XLF        EQU    0ah
  391. XESCAPE        EQU    1bh
  392. XBELL        EQU    07h
  393. XPARSIZ        EQU    10h            ; this is the size of a paragraph - this better not change!
  394. XFAERIE        EQU    00h            ; Used for dummy segment allocation
  395. X
  396. XNOERR        EQU    0
  397. XDOSERR        EQU    1
  398. XFILEERR     EQU    2
  399. XNOMEMERR    EQU    3
  400. XFILEIOERR    EQU    4
  401. XVICTIMERR    EQU    5
  402. XRELERR        EQU    6
  403. XEMSERR        EQU    7
  404. XHDRERR        EQU    8
  405. X
  406. X; The following EXTRNs are supplied by the linker
  407. X
  408. XEXTRN        $$OVLBASE:BYTE            ; segment of OVERLAY_AREA
  409. XEXTRN        $$MPGSNOVL:BYTE         ; ^ to module table
  410. XEXTRN        $$MPGSNBASE:WORD        ; ^ to module segment fixups
  411. XEXTRN        $$INTNO:BYTE            ; interrupt number to be used
  412. XEXTRN        $$COVL:WORD            ; number of physical overlays
  413. XEXTRN        $$CGSN:WORD            ; number of modules
  414. XEXTRN        $$MAIN:FAR            ; ^ to function main()
  415. X
  416. XPUBLIC        $$OVLINIT            ; Our entry point
  417. X                        ; called by the c startup code
  418. XIFDEF i386
  419. XOP32        MACRO                ; 32 bit operand override
  420. X        DB    066h
  421. X        ENDM
  422. X
  423. Xpusha        MACRO                ; push all registers
  424. X        DB    060h
  425. X        ENDM
  426. X
  427. Xpopa        MACRO                ; pop all registers
  428. X        DB    061h
  429. X        ENDM
  430. XENDIF
  431. X
  432. Xovlflgrec    RECORD    locked:1=0,ems:1=0,loaded:1=0 ; overlay flags
  433. X
  434. X; This is a dirty hack. What we need is a virtual segment that will be built
  435. X; by the (our) loader in multiple copies, one per overlay. Unfortunately, this
  436. X; doesn't seem to be a sensible idea in the minds of the folks at Microsoft.
  437. X; Declaring this segment AT will ensure that it never appears in the exefile,
  438. X; and ASSUME is dumb enough to be fooled.
  439. X;
  440. X; The reason we want to do this is also not-to-be-tried-at-home: it turns out
  441. X; that we can code a faster interrupt handler if we map overlay numbers to
  442. X; segment values. Normally we would consider this unacceptable programming
  443. X; practise because it is 86-mode specific, but the *need* for this entire
  444. X; programme is 86-mode specific, anyway.
  445. X
  446. Xpspseg        SEGMENT PARA AT FAERIE        ; dummy segment for psp
  447. X        ORG    2ch            ; ^ to segment of environmemt in psp
  448. Xpspenv        LABEL    WORD
  449. Xpspseg        ENDS
  450. X
  451. Xovltbl        SEGMENT PARA AT FAERIE        ; Dummy segment definition for overlay table
  452. X
  453. X; NOTE: This segment definition MUST be exactly 16 bytes long
  454. X
  455. Xovlflg        ovlflgrec    <0,0,0>     ; overlay flags
  456. Xovlinvcnt    DB    ?            ; invocation count
  457. Xovlmemblk    DW    ?            ; ^ to allocated memory block
  458. Xovllrudat    DD    ?            ; misc lru data (pseudo time stamp)
  459. Xovlemshdl    DW    ?            ; ovl ems memory handle
  460. Xovlfiloff    DW    ?            ; ovl file offset in pages (512 bytes)
  461. Xovlsiz        DW    ?            ; ovl size in paragraphs
  462. Xovlhdrsiz    DW    ?            ; hdr size in paragraphs
  463. X
  464. XIF1
  465. XIF        ($ - ovlflg) GT PARSIZ
  466. X        .ERR
  467. X        %OUT This segment MUST be no more than 16 bytes, REALLY!!!
  468. XENDIF
  469. XENDIF
  470. X
  471. XOVLSEGSIZ    EQU    PARSIZ            ; this had better be true!!! (16 bytes)
  472. X
  473. Xovltbl        ENDS
  474. X
  475. XEXEHDR        STRUC                ; structure of an EXE header
  476. Xexesign     DW    5a4dh            ; signature
  477. Xexelstpgesiz    DW    ?            ; last page size (512 byte pages)
  478. Xexesiz        DW    ?            ; total pages (including partial last page)
  479. Xrelocitems    DW    ?            ; number of relocation entries
  480. Xhdrparas    DW    ?            ; number of paragraphs in the header
  481. Xminalloc    DW    ?            ; minimum paragraph allocation
  482. Xmaxalloc    DW    ?            ; maximum patagraph allocation
  483. Xexess        DW    ?            ; initial stack segment
  484. Xexesp        DW    ?            ; initial stack pointer
  485. Xexechksum    DW    ?            ; checksum
  486. Xexeip        DW    ?            ; initial instruction pointer
  487. Xexecs        DW    ?            ; initial code segment
  488. Xreloctbloff    DW    ?            ; offset from beginning of header to relocation table
  489. Xexeovlnum    DW    ?            ; overlay number
  490. XEXEHDR        ENDS
  491. X
  492. XMASK_used    EQU    1            ; memory block flag
  493. X
  494. XMEMCTLBLK    STRUC                ; memory block structure
  495. Xmemblkflg    DB    ?            ; flags
  496. Xmemblkpad1    DB    ?            ; go ahead, delete me!
  497. Xmemblknxt    DW    ?            ; ^ to next block
  498. Xmemblkprv    DW    ?            ; ^ to previous block
  499. Xmemblkovl    DW    ?            ; ^ to overlay occupying this block
  500. Xmemblksiz    DW    ?            ; size in paragraphs
  501. Xmemblkpad    DB    PARSIZ - memblkpad MOD PARSIZ DUP (?) ; pad to 16 bytes
  502. XMEMCTLBLK    ENDS
  503. X
  504. XMEMCTLBLKSIZ    EQU    TYPE MEMCTLBLK / PARSIZ ; should equal 1 paragraph
  505. X
  506. X;-------------------------------------------------------------------------------
  507. X
  508. Xcode        SEGMENT PUBLIC
  509. X
  510. X; NOTE: the following order is optimum for alignment purposes across the
  511. X;    entire INTEL 80x86 family of processors.
  512. X
  513. Xovltim        DD    ?            ; pseudo-lru time variable
  514. Xfarcall     DD    ?            ; internal trampoline.
  515. Xoldvec        DD    -1            ; saved interrupt vector
  516. Xoldint21    DD    -1            ; saved int 21 vector
  517. Xsireg        DW    ?            ; temp save area
  518. XIFDEF i386
  519. X        DW    ?            ; for esi
  520. XENDIF
  521. Xdsreg        DW    ?            ; temp save area
  522. Xssreg        DW    ?
  523. Xspreg        DW    ?
  524. Xovlexefilhdl    DW    -1            ; always-open file handle of our .EXE
  525. Xovltblbse    DW    -1            ; segment of first overlay descriptor
  526. Xmemblks     DW    16 DUP (-1)        ; allocated memory blocks
  527. Xmemblk1st    DW    ?            ; first memory block
  528. Xemsmemblks    DW    16 DUP (-1)        ; ems allocated memory blocks (64K each)
  529. Xcuremshandle    DW    -1            ; currently mapped handle
  530. Xovlcnt        DW    ?            ; # overlays
  531. Xmodcnt        DW    ?            ; # of modules
  532. Xovlrootcode    DW    ?            ; logical segment of OVERLAY_AREA
  533. Xovldata     DW    ?            ; logical segment of OVERLAY_END
  534. Xpspadd        DW    ?            ; our psp address + 10h (for relocations)
  535. Xemsframe    DW    ?            ; EMM page frame segment
  536. Xmoduletbl    DD    256 DUP (?)        ; module lookup table (256 modules)
  537. Xcurovl        DW    OFFSET stkframe     ; ^ into stack frame
  538. Xstkframe    DW    256*3 DUP (?)        ; internal stack (256 ovls deep)
  539. Xtempmem     DW    16 DUP (-1)        ; temp mem block storage
  540. Xintnum        DW    ?            ; ovlmgr int number
  541. Xhdr        EXEHDR    <>            ; EXE header work area
  542. X        DB    512-TYPE EXEHDR DUP (?) ; exe hdr buffer for relocations
  543. XEXEHDRTMPSIZ    EQU    $ - hdr         ; size of temp reloc buffer
  544. Xerrortbl    DW    -1            ; error message pointers
  545. X        DW    OFFSET baddos
  546. X        DW    OFFSET nofile
  547. X        DW    OFFSET noroom
  548. X        DW    OFFSET nofile
  549. X        DW    OFFSET nocore
  550. X        DW    OFFSET nocore
  551. X        DW    OFFSET badems
  552. X        DW    OFFSET nofile
  553. X        DW    OFFSET unknown
  554. X        DW    OFFSET unknown
  555. X        DW    OFFSET unknown
  556. X        DW    OFFSET unknown
  557. X        DW    OFFSET unknown
  558. X        DW    OFFSET unknown
  559. X        DW    OFFSET unknown
  560. Xemmname     DB    "EMMXXXX0"              ; EMM device driver name
  561. Xemmtot        DW    0            ; total emm blocks free
  562. Xemmframesiz    DW    4            ; frame size in blocks
  563. Xemmflg        DB    0            ; EMM present flag
  564. X
  565. Xi386code    DB    '386 specific code enabled.',CR,LF,'$'
  566. Xmemavl        DB    'Conventional memory available: $'
  567. Xparagraphs    DB    'H paragraphs.',CR,LF,'$'
  568. Xemsavl        DB    'EMS memory available: $'
  569. Xpages        DB    'H 16K-pages.',CR,LF,'$'
  570. Xnoroom        DB    'Not enough free memory left to run this program.$'
  571. Xnocore        DB    'Internal memory allocation failure.$'
  572. Xnofile        DB    'Inaccessible EXE file. Can',27,'t load overlays.$'
  573. Xbaddos        DB    'Incorrect DOS version. Must be 3.00 or later.$'
  574. Xbadems        DB    'EMS memory manager error.$'
  575. Xunknown     DB    'Unknown error!$'
  576. Xmsghead     DB    ESCAPE,'[0m',ESCAPE,'[K',CR,LF,ESCAPE,'[K',ESCAPE,'[1mOVLMGR:',ESCAPE,'[0m $'
  577. Xdiag        DB    ESCAPE,'[K',CR,LF,ESCAPE,'[K','        ($'
  578. Xmsgtail     DB    ESCAPE,'[K',CR,LF,ESCAPE,'[K',BELL,'$'
  579. X
  580. X;-------------------------------------------------------------------------------
  581. X
  582. X$$OVLINIT    PROC    FAR            ; Init entry point
  583. X
  584. X        ASSUME    CS:code,DS:pspseg,ES:NOTHING
  585. X
  586. X        push    ax
  587. X        push    bx
  588. X        push    cx
  589. X        push    dx
  590. X        push    si
  591. X        push    di
  592. X        push    bp
  593. X        push    ds
  594. X        push    es            ; save the world
  595. X        cld
  596. X        mov    ax,ds            ; get our psp
  597. X        add    ax,10h
  598. X        mov    pspadd,ax        ; save it
  599. X        mov    ah,DOSVERSION
  600. X        int    DOS
  601. X        cmp    al,3            ; DOS 3.0 or later
  602. X        jnc    doenvthing
  603. X        mov    al,DOSERR        ; incorrect version of dos
  604. X        jmp    putserr
  605. Xdoenvthing:
  606. X        mov    ds,pspenv        ; get environment segment
  607. X        mov    si,-1
  608. Xenvloop:                    ; search for end of environment
  609. X        inc    si
  610. X        cmp    WORD PTR [si],0
  611. X        jnz    envloop
  612. X        add    si,4            ; point to EXE filename
  613. X        mov    al,0            ; access code
  614. X        mov    ah,DOSOPEN
  615. X        mov    dx,si
  616. X        int    DOS            ; open EXE
  617. X        jnc    dontdie
  618. X        mov    al,FILEERR        ; can't open file!
  619. X        jmp    putserr
  620. Xdontdie:
  621. X        mov    ovlexefilhdl,ax     ; save handle
  622. XIFNDEF NOEMS
  623. Xchkems:
  624. X        mov    ah,DOSGETVEC
  625. X        mov    al,EMM
  626. X        int    DOS
  627. X        mov    ax,cs
  628. X        mov    ds,ax
  629. X        mov    di,0ah
  630. X        mov    si,OFFSET emmname
  631. X        mov    cx,8
  632. X        repe    cmpsb
  633. X        mov    al,0
  634. X        jnz    setemmflg
  635. X        mov    al,-1
  636. Xsetemmflg:
  637. X        mov    emmflg,al
  638. X        jnz    noemshere
  639. X        mov    ah,EMMFRAME
  640. X        int    EMM
  641. X        mov    emsframe,bx
  642. X        mov    ah,EMMTOTALS
  643. X        int    EMM
  644. X        mov    emmtot,bx
  645. Xnoemshere:
  646. XENDIF
  647. X        mov    ax,SEG $$OVLBASE    ; OVERLAY_AREA segment
  648. X        mov    ovlrootcode,ax
  649. X        mov    ax,SEG $$COVL        ; segment of DGROUP
  650. X        mov    ds,ax
  651. X        mov    bx,$$CGSN        ; number of modules
  652. X        mov    modcnt,bx        ; save for later use
  653. X        mov    bx,$$COVL        ; number of physical overlays
  654. X        mov    ovlcnt,bx        ; save for later use
  655. X
  656. X; Now allocate memory
  657. X        mov    ah,DOSALLOC        ; bx contains # paras needed for ovltbl
  658. X        int    DOS
  659. X        jnc    gotovlram
  660. X        jmp    buyram
  661. Xgotovlram:
  662. X        mov    ovltblbse,ax        ; overlay descriptor table begins at start of memory block
  663. X
  664. X        push    cs
  665. X        pop    ds
  666. XIFDEF DEBUG
  667. XIFDEF i386
  668. X        mov    ah,print
  669. X        mov    dx,OFFSET msghead
  670. X        int    DOS
  671. X        mov    ah,print
  672. X        mov    dx,OFFSET i386code
  673. X        int    DOS
  674. XENDIF
  675. X        mov    ah,print
  676. X        mov    dx,OFFSET msghead
  677. X        int    DOS
  678. X        mov    ah,print
  679. X        mov    dx,OFFSET memavl
  680. X        int    DOS
  681. X        mov    ax,0a000h
  682. X        sub    ax,ovltblbse
  683. X        call    itoa
  684. X        mov    ah,print
  685. X        mov    dx,OFFSET paragraphs
  686. X        int    DOS
  687. XIFNDEF NOEMS
  688. X        mov    ah,print
  689. X        mov    dx,OFFSET msghead
  690. X        int    DOS
  691. X        mov    ah,print
  692. X        mov    dx,OFFSET emsavl
  693. X        int    DOS
  694. X        mov    ax,emmtot
  695. X        call    itoa
  696. X        mov    ah,print
  697. X        mov    dx,OFFSET pages
  698. X        int    DOS
  699. XENDIF
  700. XENDIF
  701. X        ASSUME    ES:ovltbl
  702. X
  703. X        xor    bp,bp
  704. X        xor    di,di
  705. X        xor    si,si
  706. Xfilsegtbllpp:                    ; initialise ovl table
  707. X        call    gethdr            ; get an EXE header
  708. X        mov    ax,ovltblbse
  709. X        add    ax,hdr.exeovlnum
  710. X        mov    es,ax            ; ^ to ovl table entry
  711. X        xor    ax,ax
  712. X        mov    WORD PTR ovllrudat,ax    ; initialise ovl lru
  713. X        mov    WORD PTR ovllrudat+2,ax
  714. X        mov    ovlflg,al        ; initialise ovl flags
  715. X        mov    ovlinvcnt,al        ; initialise invocation count
  716. X        mov    ovlemshdl,-1
  717. X        mov    ax,hdr.exesiz
  718. X        shl    ax,1
  719. X        shl    ax,1
  720. X        shl    ax,1
  721. X        shl    ax,1
  722. X        shl    ax,1            ; * 32
  723. X        mov    dx,hdr.exelstpgesiz
  724. X        or    dx,dx
  725. X        jz    emptypage
  726. X        shr    dx,1
  727. X        shr    dx,1
  728. X        shr    dx,1
  729. X        shr    dx,1            ; / 16
  730. X        inc    dx
  731. X        sub    ax,20h
  732. X        add    ax,dx
  733. Xemptypage:
  734. X        sub    ax,hdr.hdrparas     ; actual size of code
  735. X        mov    ovlsiz,ax        ; overlay size in paragraphs
  736. X        cmp    hdr.exeovlnum,0     ; skip if ovl 0 (root code)
  737. X        jz    notlargest
  738. X        cmp    ax,di            ; find largest ovl
  739. X        jc    notlargest
  740. X        mov    di,ax
  741. Xnotlargest:
  742. X        mov    ax,hdr.hdrparas
  743. X        shl    ax,1
  744. X        shl    ax,1
  745. X        shl    ax,1
  746. X        shl    ax,1
  747. X        mov    ovlhdrsiz,ax        ; hdr size in bytes
  748. X        mov    ovlfiloff,bp        ; initialise ovl file offset
  749. X        add    bp,hdr.exesiz        ; ^ to next overlay
  750. X        mov    dx,bp
  751. X        mov    cl,dh
  752. X        mov    dh,dl
  753. X        xor    ch,ch
  754. X        xor    dl,dl
  755. X        shl    dx,1
  756. X        rcl    cx,1            ; cx:dx = bp * 512
  757. X        mov    al,0
  758. X        mov    ah,DOSSEEK        ; seek to next ovl
  759. X        int    DOS
  760. X        mov    ax,ovlcnt
  761. X        dec    ax
  762. X        cmp    ax,hdr.exeovlnum    ; all overlays done?
  763. X        jz    makmemblk
  764. X        jmp    filsegtbllpp        ; Nope, go for more.
  765. Xmakmemblk:
  766. X        ASSUME    ES:nothing        ; prepare first memory block
  767. X
  768. X        mov    ax,ovlrootcode        ; OVERLAY_AREA segment
  769. X        mov    memblk1st,ax        ; save pointer to first mem block
  770. X        mov    es,ax
  771. X        mov    es:memblkflg,0        ; clear mem flags
  772. X        mov    es:memblknxt,0        ; set next to nothing
  773. X        mov    es:memblkprv,0        ; set previous to nothing
  774. X        mov    es:memblkovl,0        ; no overlay loaded
  775. X        mov    es:memblksiz,di     ; di contains OVERLAY_AREA size in paragraphs
  776. X        add    ax,di
  777. X        mov    ovldata,ax        ; end of OVERLAY_END
  778. X        push    di
  779. X        mov    es,ovltblbse        ; temporary
  780. X        call    getemsmem        ; see if any ems available
  781. X        mov    es:ovlemshdl,-1     ; fix these!
  782. X        and    es:ovlflg,NOT MASK ems
  783. X        push    dx
  784. X        call    getmoreram        ; see if there are any other pieces lying around
  785. X        pop    ax
  786. X        pop    di
  787. X        or    ax,ax            ; any ems?
  788. X        jnz    noramcheck
  789. X        inc    di
  790. X        cmp    dx,di
  791. X        jc    buyram
  792. Xnoramcheck:
  793. X        mov    WORD PTR ovltim,0    ; initialise global lru time stamp
  794. X        mov    WORD PTR ovltim+2,0
  795. X        mov    di,OFFSET stkframe
  796. X        mov    WORD PTR cs:[di],-1    ; initialise stack frame
  797. X        add    di,6
  798. X        mov    ax,ovltblbse
  799. X        mov    cs:[di],ax
  800. X        mov    curovl,di        ; initialise stack frame pointer
  801. X        mov    es,ax
  802. X        mov    es:ovlflg,MASK locked OR MASK loaded ; set flags on ovl 0
  803. X        jmp    short chgintvec
  804. Xbuyram:
  805. X        mov    al,NOMEMERR        ; free up some TSRs or something
  806. X        jmp    putserr
  807. Xchgintvec:
  808. X        mov    ax,SEG $$INTNO
  809. X        mov    ds,ax
  810. X        mov    al,$$INTNO        ; get int number to use
  811. X        xor    ah,ah
  812. X        shl    ax,1
  813. X        shl    ax,1
  814. X        mov    intnum,ax
  815. X        call    setvectors        ; set up interrupt vectors
  816. X        mov    cx,modcnt        ; module count
  817. X        mov    ax,SEG $$MPGSNBASE
  818. X        mov    es,ax
  819. X        mov    ax,cs
  820. X        mov    ds,ax
  821. X
  822. X        ASSUME    DS:code
  823. X
  824. X        mov    bx,OFFSET $$MPGSNBASE    ; ^ to linker provided overlay segment fixups
  825. X        mov    si,OFFSET $$MPGSNOVL    ; ^ to linker provided module table
  826. X        mov    di,OFFSET moduletbl    ; ^ to our module table
  827. Xmodloop:
  828. X        mov    al,es:[si]        ; real physical ovl number
  829. X        xor    ah,ah
  830. X        add    ax,ovltblbse        ; ovlctlseg address
  831. X        mov    [di],ax         ; save in module table
  832. X        mov    ax,es:[bx]        ; get seg fixup
  833. X        sub    ax,ovlrootcode        ; adjust for relative reference
  834. X        mov    [di+2],ax        ; save in module table
  835. X        add    di,4
  836. X        add    bx,2
  837. X        inc    si
  838. X        loop    modloop
  839. X        pop    es
  840. X        pop    ds
  841. X        pop    bp
  842. X        pop    di
  843. X        pop    si
  844. X        pop    dx
  845. X        pop    cx
  846. X        pop    bx
  847. X        pop    ax            ; restore the world
  848. X        jmp    $$MAIN            ; And away we go!
  849. X
  850. X$$OVLINIT    ENDP
  851. X
  852. X;-------------------------------------------------------------------------------
  853. X
  854. Xovlmgr        PROC    FAR            ; This is the it!
  855. X
  856. X        ASSUME    DS:NOTHING,ES:NOTHING
  857. X
  858. XIFDEF i386
  859. X        OP32
  860. XENDIF
  861. X        mov    sireg,si        ; preserve si
  862. X        mov    dsreg,ds        ; and ds
  863. X        pop    si            ; retrieve caller ip
  864. X        pop    ds            ;     "      "    cs
  865. X        push    ax
  866. X        push    bx
  867. X        cld
  868. X        lodsb                ; module # to call
  869. X        xor    ah,ah
  870. X        mov    bx,ax
  871. X        lodsw                ; offset in ovl to call
  872. X        mov    WORD PTR farcall,ax    ; into trampoline
  873. X        mov    ax,si
  874. X        mov    si,curovl        ; get stack frame pointer
  875. X        add    si,6            ; update stack
  876. X        mov    cs:[si-4],ds        ; save return seg
  877. X        mov    cs:[si-2],ax        ; and return offset
  878. X
  879. X        shl    bx,1
  880. X        shl    bx,1            ; * 4 (2 words/entry in module tbl)
  881. X        add    bx,OFFSET moduletbl
  882. X        mov    ds,cs:[bx]        ; ovl tbl entry
  883. X        mov    ax,cs:[bx+2]        ; segment fixup
  884. X        mov    cs:[si],ds        ; ovl entry into stack frame
  885. X        mov    curovl,si
  886. X
  887. X        ASSUME    DS:ovltbl
  888. X
  889. XIFDEF i386
  890. X        OP32
  891. XENDIF
  892. X        mov    si,WORD PTR ovltim    ; lru time stamp
  893. XIFDEF i386
  894. X        OP32
  895. XENDIF
  896. X        inc    si            ; time passes!
  897. XIFDEF i386
  898. X        OP32
  899. XENDIF
  900. X        mov    WORD PTR ovltim,si    ; update global clock
  901. XIFDEF i386
  902. X        OP32
  903. XENDIF
  904. X        mov    WORD PTR ovllrudat,si    ; as well as ovl clock
  905. XIFNDEF i386
  906. X        mov    si,WORD PTR ovltim+2
  907. X        jz    ininc            ; dword increment
  908. Xcryupcdon:
  909. X        mov    WORD PTR ovllrudat+2,si ; as well as ovl clock
  910. XENDIF
  911. X        test    ovlflg,MASK loaded    ; ovl loaded?
  912. X        jz    inload            ; load it or map it then.
  913. Xovlloadedupc:
  914. X        inc    ovlinvcnt
  915. X        add    ax,ovlmemblk        ; add fixup and segment address
  916. X        mov    WORD PTR farcall+2,ax    ; into trampoline
  917. XIFDEF i386
  918. X        OP32
  919. XENDIF
  920. X        mov    si,sireg        ; retore all registers
  921. X        mov    ds,dsreg
  922. X        pop    bx
  923. X        pop    ax
  924. X        popf                ; don't forget these!
  925. X        call    DWORD PTR farcall    ; and GO
  926. X        pushf                ; preserve registers again!
  927. X        mov    dsreg,ds
  928. XIFDEF i386
  929. X        OP32
  930. XENDIF
  931. X        mov    sireg,si
  932. X        mov    si,curovl        ; stack frame pointer
  933. X        mov    ds,cs:[si]
  934. X        dec    ovlinvcnt
  935. X        sub    si,6            ; adjust stack
  936. X        mov    ds,cs:[si]        ; retrieve ovl tbl entry
  937. X        push    cs:[si+2]        ; set return address
  938. X        push    cs:[si+4]
  939. X        mov    curovl,si
  940. XIFDEF i386
  941. X        OP32
  942. XENDIF
  943. X        mov    si,WORD PTR ovltim    ; do the lru thing again
  944. XIFDEF i386
  945. X        OP32
  946. XENDIF
  947. X        inc    si
  948. XIFDEF i386
  949. X        OP32
  950. XENDIF
  951. X        mov    WORD PTR ovltim,si
  952. XIFDEF i386
  953. X        OP32
  954. XENDIF
  955. X        mov    WORD PTR ovllrudat,si
  956. XIFNDEF i386
  957. X        mov    si,WORD PTR ovltim+2
  958. X        jz    outinc
  959. Xcrydncdon:
  960. X        mov    WORD PTR ovllrudat+2,si
  961. XENDIF
  962. X        test    ovlflg,MASK loaded    ; ovl loaded?
  963. X        jz    outload         ; better get it before someone notices
  964. Xjmpback:
  965. XIFDEF i386
  966. X        OP32
  967. XENDIF
  968. X        mov    si,sireg        ; get registers back
  969. X        mov    ds,dsreg
  970. X        iret                ; and GO back
  971. X
  972. XIFNDEF i386
  973. Xininc:
  974. X        inc    si
  975. X        mov    WORD PTR ovltim+2,si    ; update global and
  976. X        jmp    cryupcdon
  977. XENDIF
  978. X
  979. Xinload:
  980. X        test    ovlflg,MASK ems
  981. X        jz    infile
  982. X        push    ax
  983. X        mov    ax,ovlemshdl
  984. X        call    mappage
  985. X        pop    ax
  986. X        jmp    ovlloadedupc
  987. Xinfile:
  988. X        call    loadoverlay        ; self explanatory
  989. X        jmp    ovlloadedupc
  990. X
  991. XIFNDEF i386
  992. Xoutinc:
  993. X        inc    si
  994. X        mov    WORD PTR ovltim+2,si
  995. X        jmp    crydncdon
  996. XENDIF
  997. X
  998. Xoutload:
  999. X        test    ovlflg,MASK ems
  1000. X        jz    outfile
  1001. X        push    ax
  1002. X        mov    ax,ovlemshdl
  1003. X        call    mappage
  1004. X        pop    ax
  1005. X        jmp    jmpback
  1006. Xoutfile:
  1007. X        call    loadoverlay
  1008. X        jmp    jmpback
  1009. X
  1010. Xovlmgr        ENDP
  1011. X
  1012. X;-------------------------------------------------------------------------------
  1013. X
  1014. Xloadoverlay    PROC    NEAR            ; load overlay pointed to by es
  1015. X
  1016. X        ASSUME    DS:NOTHING,ES:ovltbl
  1017. X
  1018. XIFDEF i386
  1019. X        OP32
  1020. X        pusha                   ; eax,ecx,edx,ebx,esp,ebp,esi,edi
  1021. XELSE
  1022. X        push    ax
  1023. X        push    cx
  1024. X        push    dx
  1025. X        push    bx
  1026. X        push    bp
  1027. X        push    si
  1028. X        push    di
  1029. XENDIF
  1030. X        push    ds
  1031. X        push    es            ; just in case
  1032. X        mov    ax,ds
  1033. X        mov    es,ax
  1034. X        cmp    ovlinvcnt,0
  1035. X        jnz    fxdadr            ; Yup, it's a toughie
  1036. X        mov    ax,ovlsiz        ; How much?
  1037. X        call    getpages        ; never fail mem alloc, you bet.
  1038. X        jmp    gleaner
  1039. Xfxdadr:
  1040. X        call    releasepages        ; free memory where this ovl should be loaded
  1041. Xgleaner:
  1042. X        add    ax,MEMCTLBLKSIZ     ; skip mem ctl blk
  1043. X        mov    ovlmemblk,ax        ; memory block to use
  1044. X        mov    ds,ax
  1045. X        mov    dx,ovlfiloff        ; where in the file is it?
  1046. X        mov    cl,dh
  1047. X        mov    dh,dl
  1048. X        xor    ch,ch
  1049. X        xor    dl,dl
  1050. X        shl    dx,1
  1051. X        rcl    cx,1            ; cx:dx = dx * 512
  1052. X        mov    ax,ovlhdrsiz
  1053. X        push    cx
  1054. X        push    dx
  1055. X        add    dx,ax
  1056. X        adc    cx,0            ; position to code
  1057. X        mov    ah,DOSSEEK        ; lseek to code
  1058. X        mov    al,0            ; from beginning of file
  1059. X        mov    bx,ovlexefilhdl     ; never closing handle
  1060. X        int    DOS
  1061. X        jc    burnhead        ; oops!
  1062. X        xor    dx,dx            ; buf = ds:0
  1063. X        mov    cx,ovlsiz        ; number of paragraphs to load
  1064. X        shl    cx,1
  1065. X        shl    cx,1
  1066. X        shl    cx,1
  1067. X        shl    cx,1            ; * 16 = number of bytes
  1068. X        mov    ah,DOSREAD        ; prevent random DOS behaviour
  1069. X        int    DOS            ; read in code
  1070. X        jc    burnhead        ; double oops!
  1071. X        pop    dx
  1072. X        pop    cx            ; position of hdr
  1073. X        mov    ah,DOSSEEK        ; lseek to hdr
  1074. X        mov    al,0            ; from beginning of file
  1075. X        mov    bx,ovlexefilhdl     ; never closing handle
  1076. X        int    DOS
  1077. X        jc    burnhead        ; oops!
  1078. X        mov    cx,EXEHDRTMPSIZ     ; reloc buffer size
  1079. X        mov    dx,OFFSET hdr
  1080. X        push    ds
  1081. X        mov    ax,cs
  1082. X        mov    ds,ax
  1083. X        mov    ah,DOSREAD        ; prevent random DOS behaviour
  1084. X        int    DOS            ; read in header
  1085. X        pop    ds
  1086. X        jc    burnhead        ; double oops!
  1087. X
  1088. X        call    ovlrlc            ; perform relocation normally done by DOS EXE loader
  1089. X        pop    es            ; retrieve ovl tbl entry
  1090. X        pop    ds
  1091. X
  1092. X        ASSUME    DS:ovltbl,ES:NOTHING
  1093. X
  1094. X        or    ovlflg,MASK loaded    ; because it is now
  1095. XIFDEF i386
  1096. X        OP32
  1097. X        popa
  1098. XELSE
  1099. X        pop    di
  1100. X        pop    si
  1101. X        pop    bp
  1102. X        pop    bx
  1103. X        pop    dx
  1104. X        pop    cx
  1105. X        pop    ax
  1106. XENDIF
  1107. X        ret
  1108. X
  1109. Xburnhead:
  1110. X        mov    al,FILEIOERR        ; some kind of I/O error
  1111. X        jmp    putserr
  1112. X
  1113. Xloadoverlay    ENDP
  1114. X
  1115. X;-------------------------------------------------------------------------------
  1116. X
  1117. Xovlrlc        PROC    NEAR            ; ds:0 -> the overlay to relocate
  1118. X
  1119. X        ASSUME    DS:NOTHING,ES:NOTHING
  1120. X
  1121. X        mov    si,OFFSET hdr
  1122. X        mov    bp,si
  1123. X        add    bp,EXEHDRTMPSIZ     ; ^ to end of buf+1
  1124. X        mov    cx,cs:[si.relocitems]    ; roto-count
  1125. X        jcxz    relocdone        ; not such a good idea, after all
  1126. X        mov    di,ds
  1127. X        sub    di,ovlrootcode        ; segment fixup value
  1128. X        add    si,cs:[si.reloctbloff]    ; ^ relocation table
  1129. Xdorelocs:                    ; labels don't GET comments
  1130. X        cmp    si,bp            ; past the end ?
  1131. X        jc    getoffsetl
  1132. X        call    getnxtreloc        ; get another hunk
  1133. Xgetoffsetl:
  1134. X        mov    bl,cs:[si]        ; offset into load module
  1135. X        inc    si
  1136. X        cmp    si,bp            ; past the end ?
  1137. X        jc    getoffseth
  1138. X        call    getnxtreloc        ; get another hunk
  1139. Xgetoffseth:
  1140. X        mov    bh,cs:[si]        ; offset into load module
  1141. X        inc    si
  1142. X        cmp    si,bp            ; past the end ?
  1143. X        jc    getsegmentl
  1144. X        call    getnxtreloc        ; get another hunk
  1145. Xgetsegmentl:
  1146. X        mov    al,cs:[si]        ; segment in load module (zero reference)
  1147. X        inc    si
  1148. X        cmp    si,bp            ; past the end ?
  1149. X        jc    getsegmenth
  1150. X        call    getnxtreloc        ; get another hunk
  1151. Xgetsegmenth:
  1152. X        mov    ah,cs:[si]        ; segment in load module (zero reference)
  1153. X        inc    si
  1154. X        add    ax,pspadd        ; now it is psp relative
  1155. X        add    ax,di            ; and now it is relative to the actual load address
  1156. X        mov    es,ax
  1157. X        mov    ax,es:[bx]        ; pickup item to relocate
  1158. X        add    ax,pspadd        ; make it psp relative
  1159. X        cmp    ax,ovlrootcode        ; is it below the OVERLAY_AREA?
  1160. X        jc    reloccomputed        ; yup. it's relocated
  1161. X        cmp    ax,ovldata        ; is it above OVERLAY_AREA
  1162. X        jnc    reloccomputed        ; yup. it's relocated
  1163. X        add    ax,di            ; it's in OVERLAY_AREA, this one's ours.
  1164. Xreloccomputed:
  1165. X        mov    es:[bx],ax        ; RAM it home!?!
  1166. X        loop    dorelocs        ; what goes around, comes around.
  1167. Xrelocdone:    ret
  1168. X
  1169. Xovlrlc        ENDP
  1170. X
  1171. X;-------------------------------------------------------------------------------
  1172. X
  1173. Xgetnxtreloc    PROC    NEAR
  1174. X
  1175. X        ASSUME    DS:NOTHING,ES:NOTHING
  1176. X
  1177. X        push    bx
  1178. X        push    cx
  1179. X        push    di
  1180. X        push    bp
  1181. X        push    ds
  1182. X        push    es
  1183. X        mov    cx,EXEHDRTMPSIZ     ; reloc buffer size
  1184. X        mov    dx,OFFSET hdr
  1185. X        mov    ax,cs
  1186. X        mov    ds,ax
  1187. X        mov    bx,ovlexefilhdl     ; never closing handle
  1188. X        mov    ah,DOSREAD        ; prevent random DOS behaviour
  1189. X        int    DOS            ; read in header
  1190. X        jnc    nxtrelocok
  1191. X        jmp    burnhead        ; double oops!
  1192. Xnxtrelocok:
  1193. X        mov    si,OFFSET hdr
  1194. X        pop    es
  1195. X        pop    ds
  1196. X        pop    bp
  1197. X        pop    di
  1198. X        pop    cx
  1199. X        pop    bx
  1200. X        ret
  1201. X
  1202. Xgetnxtreloc    ENDP
  1203. X
  1204. X;-------------------------------------------------------------------------------
  1205. X
  1206. Xgetvictim    PROC    NEAR            ; select a victim to discard (and free up some memory)
  1207. X
  1208. X        ASSUME    DS:ovltbl,ES:NOTHING
  1209. X
  1210. X        push    bx
  1211. X        push    cx
  1212. X        push    dx
  1213. X        push    si
  1214. X        push    di
  1215. X        push    bp
  1216. X        push    ds
  1217. X        mov    ds,ovltblbse        ; ^ ovl tbl
  1218. XIFDEF i386
  1219. X        OP32
  1220. XENDIF
  1221. X        xor    ax,ax            ; will contain the low word of lru
  1222. XIFDEF i386
  1223. X        OP32
  1224. XENDIF
  1225. X        mov    dx,ax            ; will contain the high word of lru
  1226. X        mov    bp,ax            ; will contain ovl tbl entry
  1227. X        mov    bx,ax            ; ovl tbl ptr
  1228. X        mov    cx,ovlcnt
  1229. Xfoon1:
  1230. X        test    ovlflg[bx],MASK locked
  1231. X        jnz    skip1
  1232. X        test    ovlflg[bx],MASK ems
  1233. X        jnz    foon2
  1234. X        test    ovlflg[bx],MASK loaded
  1235. X        jz    skip1
  1236. Xfoon2:
  1237. XIFDEF i386
  1238. X        OP32
  1239. XENDIF
  1240. X        mov    si,WORD PTR ovltim
  1241. XIFNDEF i386
  1242. X        mov    di,WORD PTR ovltim+2
  1243. XENDIF
  1244. XIFDEF i386
  1245. X        OP32
  1246. XENDIF
  1247. X        sub    si,WORD PTR ovllrudat[bx]
  1248. XIFNDEF i386
  1249. X        sbb    di,WORD PTR ovllrudat[bx+2]
  1250. XENDIF
  1251. XIFDEF i386
  1252. X        OP32
  1253. X        cmp    dx,si
  1254. XELSE
  1255. X        cmp    dx,di
  1256. XENDIF
  1257. XIFDEF i386
  1258. X        jnc    skip1
  1259. XELSE
  1260. X        jc    better1
  1261. X        jnz    skip1
  1262. X        cmp    ax,si
  1263. X        jnc    skip1
  1264. XENDIF
  1265. Xbetter1:
  1266. XIFDEF i386
  1267. X        OP32
  1268. X        mov    dx,si
  1269. XELSE
  1270. X        mov    ax,si
  1271. X        mov    dx,di
  1272. XENDIF
  1273. X        mov    bp,bx
  1274. Xskip1:
  1275. X        add    bx,OVLSEGSIZ
  1276. X        loop    foon1
  1277. X        or    bp,bp            ; were we more successful this time?
  1278. X        jnz    gotvictim        ; now we got one.
  1279. Xnomoremem:
  1280. X        mov    al,VICTIMERR        ; were really %$# now!
  1281. X        jmp    putserr
  1282. Xgotvictim:
  1283. X        shr    bp,1            ; convert offset to segment
  1284. X        shr    bp,1
  1285. X        shr    bp,1
  1286. X        shr    bp,1
  1287. X        mov    ax,ds
  1288. X        add    ax,bp
  1289. X        pop    ds
  1290. X        pop    bp
  1291. X        pop    di
  1292. X        pop    si
  1293. X        pop    dx
  1294. X        pop    cx
  1295. X        pop    bx
  1296. X        ret
  1297. X
  1298. Xgetvictim    ENDP
  1299. X
  1300. X;-------------------------------------------------------------------------------
  1301. X
  1302. Xint21        PROC    FAR
  1303. X
  1304. X; free almost all overlay memory if app. tries to call the DOS exec function.
  1305. X
  1306. X        cmp    ah,DOSEXEC
  1307. X        jz    freeall
  1308. X        cmp    ah,TERMINATE
  1309. X        jz    saybyebye
  1310. Xnotours:
  1311. X        jmp    cs:oldint21
  1312. Xsaybyebye:
  1313. X        mov    al,NOERR        ; return code 0
  1314. X        jmp    putserr
  1315. Xfreeall:
  1316. X        or    al,al            ; is it load and exec?
  1317. X        jnz    notours
  1318. X        push    ax
  1319. X        push    cx
  1320. X        push    dx
  1321. X        push    bx
  1322. X        push    bp
  1323. X        push    si
  1324. X        push    di
  1325. X        push    es
  1326. X        push    ds            ; preserve calling env.
  1327. X
  1328. X        ASSUME    DS:NOTHING,ES:ovltbl
  1329. X
  1330. X        mov    es,ovltblbse
  1331. X        mov    cx,ovlcnt        ; unload all overlays that are
  1332. X        mov    bx,OVLSEGSIZ        ; in EMS or are in alloced mem.
  1333. X        dec    cx
  1334. Xmemunloadlp:
  1335. X        test    [bx.ovlflg],MASK ems
  1336. X        jnz    memunload
  1337. X        test    [bx.ovlflg],MASK loaded
  1338. X        jz    nxtmemunload
  1339. X        mov    ax,[bx.ovlmemblk]
  1340. X        sub    ax,MEMCTLBLKSIZ
  1341. X        cmp    ax,memblks        ; allocated memory ?
  1342. X        jc    nxtmemunload
  1343. Xmemunload:
  1344. X        and    [bx.ovlflg],NOT MASK loaded ; you're outta there!
  1345. Xnxtmemunload:
  1346. X        add    bx,OVLSEGSIZ
  1347. X        loop    memunloadlp
  1348. X
  1349. X        mov    curemshandle,-1     ; no current handle anymore
  1350. X
  1351. X        mov    ax,memblks
  1352. X        cmp    ax,-1
  1353. X        jz    nosecondblk
  1354. X        mov    es,ax            ; ^ to second mem blk
  1355. X        mov    es,es:memblkprv     ; get previous pointer
  1356. X        mov    es:memblknxt,0        ; no other blocks after this one
  1357. Xnosecondblk:
  1358. X        mov    cx,16            ; do all allocated mem blocks
  1359. X        mov    si,OFFSET memblks
  1360. Xfreememblklp:
  1361. X        mov    ax,cs:[si]        ; get memory blk segment
  1362. X        cmp    ax,-1            ; was one ever allocated?
  1363. X        jz    nxtmemblklp        ; nope
  1364. X        mov    es,ax
  1365. X        mov    ah,DOSFREE        ; must free it.
  1366. X        int    DOS
  1367. X        mov    WORD PTR cs:[si],-1
  1368. Xnxtmemblklp:
  1369. X        add    si,2
  1370. X        loop    freememblklp
  1371. X
  1372. X        call    rstvectors        ; restore all int vectors
  1373. X
  1374. X        mov    bp,sp
  1375. X        push    [bp+22]         ; ensure returned flags are based on user's!
  1376. X        popf
  1377. X        pop    ds
  1378. X        pop    es
  1379. X        pop    di
  1380. X        pop    si
  1381. X        pop    bp
  1382. X        pop    bx
  1383. X        pop    dx
  1384. X        pop    cx
  1385. X        pop    ax
  1386. X
  1387. X        mov    ssreg,ss        ; preserve these due to a
  1388. X        mov    spreg,sp        ; DOS bug.
  1389. X
  1390. X        int    DOS            ; allow DOS to continue!
  1391. X
  1392. X        mov    ss,ssreg
  1393. X        mov    sp,spreg
  1394. X
  1395. X        push    ax
  1396. X        push    cx
  1397. X        push    dx
  1398. X        push    bx
  1399. X        push    bp
  1400. X        push    si
  1401. X        push    di
  1402. X        push    es
  1403. X        push    ds            ; preserve calling env.
  1404. X        mov    bp,sp
  1405. X        pushf
  1406. X        pop    [bp+22]         ; fix return flags
  1407. X
  1408. X        call    getmoreram        ; re-allocate our memory
  1409. X        call    setvectors        ; patch vectors again
  1410. X
  1411. X        pop    ds
  1412. X        pop    es
  1413. X        pop    di
  1414. X        pop    si
  1415. X        pop    bp
  1416. X        pop    bx
  1417. X        pop    dx
  1418. X        pop    cx
  1419. X        pop    ax
  1420. X        iret
  1421. X
  1422. Xint21        ENDP
  1423. X
  1424. X;-------------------------------------------------------------------------------
  1425. X
  1426. Xreleasepages    PROC    NEAR            ; Arg in es, result in ax
  1427. X
  1428. X; release any memory (and overlays) where this overlay should reside
  1429. X
  1430. X        ASSUME    DS:NOTHING,ES:ovltbl
  1431. X
  1432. X        mov    bx,ovlmemblk        ; start of memory to release
  1433. X        sub    bx,MEMCTLBLKSIZ
  1434. X        mov    dx,bx
  1435. X        add    dx,es:ovlsiz
  1436. X        add    dx,MEMCTLBLKSIZ     ; end of memory to release
  1437. X        mov    ax,ovlemshdl
  1438. X        cmp    ax,-1
  1439. X        jz    doitagain
  1440. X        call    mappage
  1441. X        or    ovlflg,MASK ems
  1442. X        mov    ax,emsframe
  1443. X        jmp    dvart
  1444. Xdoitagain:
  1445. X        mov    ax,memblk1st        ; first memory blk
  1446. X        jmp    dvart
  1447. Xdvartloop:
  1448. X        mov    ds,ax            ; memory blk to check
  1449. X        cmp    bx,ax            ; does it start below the memory to release?
  1450. X        jnc    dvartsmaller        ; yup
  1451. X        cmp    ax,dx            ; does it start above?
  1452. X        jnc    dvartnocore        ; yup
  1453. X        call    killmem         ; it's in the way. Zap it.
  1454. X        jmp    dvartloop
  1455. Xdvartsmaller:
  1456. X        add    ax,ds:memblksiz     ; end of this memory blk
  1457. X        cmp    bx,ax            ; does it end below the memory to release?
  1458. X        jnc    dvartsilly        ; yup
  1459. X        test    ds:memblkflg,MASK_used
  1460. X        jz    dvartfree
  1461. X        call    killmem         ; Oh well, zap it too.
  1462. X        add    ax,ds:memblksiz     ; end of this memory blk
  1463. Xdvartfree:
  1464. X        cmp    ax,dx            ; does it end in the memory to be released?
  1465. X        jc    dvartsilly
  1466. Xdvartgotblk:
  1467. X        mov    ax,ds            ; this is it!
  1468. X        mov    cx,bx
  1469. X        sub    cx,ax            ; # of paragraphs between start of memory to release and mem blk
  1470. X        jz    nosplit
  1471. X        push    es
  1472. X        call    splitblk
  1473. X        or    es:memblkflg,MASK_used    ; set high block used
  1474. X        call    mergemem        ; merge remaining free memory
  1475. X        mov    ax,es
  1476. X        mov    ds,ax
  1477. X        pop    es
  1478. Xnosplit:
  1479. X        mov    cx,es:ovlsiz
  1480. X        add    cx,MEMCTLBLKSIZ     ; paragraphs needed to load ovl
  1481. X        jmp    splitblklow        ; split remaining block
  1482. Xdvartsilly:
  1483. X        mov    ax,ds:memblknxt
  1484. Xdvart:
  1485. X        or    ax,ax            ; end of mem list?
  1486. X        jz    dvartnocore
  1487. X        jmp    dvartloop        ; play it again Sam.
  1488. Xdvartnocore:
  1489. X        mov    al,RELERR        ; super OOPS!
  1490. X        jmp    putserr
  1491. X
  1492. Xreleasepages    ENDP
  1493. X
  1494. X;-------------------------------------------------------------------------------
  1495. X
  1496. Xgetpages    PROC    NEAR            ; get enough memory to load ovl
  1497. X
  1498. X        ASSUME    DS:NOTHING,ES:ovltbl
  1499. X
  1500. X        mov    ovlemshdl,-1        ; clear any EMS stuff
  1501. X        and    ovlflg,NOT MASK ems
  1502. X        mov    cx,ax
  1503. X        add    cx,MEMCTLBLKSIZ     ; total paragraphs needed
  1504. Xdorkagain:
  1505. X        call    largestmem        ; find largest free blk
  1506. X        cmp    dx,cx            ; large enough?
  1507. X        jnc    gotdork         ; yup.
  1508. X        call    getemsmem        ; try to allocate ems
  1509. X        cmp    dx,cx            ; any available ?
  1510. X        jnc    gotdork
  1511. Xdorkkill:
  1512. X        call    getvictim        ; select a victim to release
  1513. X        call    killovl         ; kill the selected victim
  1514. X        jmp    dorkagain
  1515. Xgotdork:
  1516. X        jmp    splitblklow        ; split the free blk
  1517. X
  1518. Xgetpages    ENDP
  1519. X
  1520. X;-------------------------------------------------------------------------------
  1521. X
  1522. Xsplitblklow    PROC    NEAR
  1523. X
  1524. X; split a block of memory returning the lower one to be used.
  1525. X
  1526. X        ASSUME    DS:NOTHING,ES:NOTHING
  1527. X
  1528. X        push    es
  1529. X        or    ds:memblkflg,MASK_used    ; set low block used
  1530. X        call    splitblk
  1531. X        jc    splitlowdone
  1532. X        push    ds
  1533. X        mov    ax,es
  1534. X        mov    ds,ax
  1535. X        call    mergemem        ; merge remaining free memory
  1536. X        pop    ds
  1537. Xsplitlowdone:
  1538. X        pop    es
  1539. X        mov    ds:memblkovl,es     ; fix ptr to ovl
  1540. X        mov    ax,ds            ; return lower blk segment
  1541. X        ret
  1542. X
  1543. Xsplitblklow    ENDP
  1544. X
  1545. X;-------------------------------------------------------------------------------
  1546. X
  1547. Xsplitblk    PROC    NEAR
  1548. X
  1549. X        ASSUME    DS:NOTHING,ES:NOTHING
  1550. X
  1551. X        mov    ax,ds
  1552. X        add    ax,cx
  1553. X        mov    es,ax            ; ^ to upper blk to be created
  1554. X        mov    ax,ds:memblksiz
  1555. X        sub    ax,cx
  1556. X        jbe    nofix            ; must be at least 1 para remaining to split
  1557. X        mov    ds:memblksiz,cx     ; fix blk sizes
  1558. X        mov    es:memblksiz,ax
  1559. X        mov    ax,ds:memblknxt     ; fix pointers
  1560. X        mov    es:memblknxt,ax
  1561. X        mov    ds:memblknxt,es
  1562. X        mov    es:memblkprv,ds
  1563. X        mov    es:memblkflg,0        ; set upper to not used
  1564. X        mov    ax,es:memblknxt
  1565. X        or    ax,ax
  1566. X        jz    nofix
  1567. X        push    ds
  1568. X        mov    ds,ax            ; fix blk after upper to point to upper
  1569. X        mov    ds:memblkprv,es
  1570. X        pop    ds
  1571. X        clc
  1572. X        ret
  1573. Xnofix:
  1574. X        stc
  1575. X        ret
  1576. X
  1577. Xsplitblk    ENDP
  1578. X
  1579. X;-------------------------------------------------------------------------------
  1580. X
  1581. Xlargestmem    PROC    NEAR    ; returns seg in ax, size in dx
  1582. X                ; retruns first block that's large enough if possible
  1583. X
  1584. X        ASSUME    DS:NOTHING,ES:ovltbl
  1585. X
  1586. X        mov    ax,memblk1st        ; first mem blk
  1587. X        xor    dx,dx            ; largest size found
  1588. X        jmp    gook
  1589. Xgookloop:
  1590. X        mov    ds,ax
  1591. X        test    ds:memblkflg,MASK_used    ; is this blk used?
  1592. X        jnz    gookme            ; yup
  1593. X        cmp    ds:memblksiz,cx     ; is it large enough?
  1594. X        jc    gookme            ; nope
  1595. X        mov    dx,ds:memblksiz     ; got one!
  1596. X        ret
  1597. Xgookme:
  1598. X        mov    ax,ds:memblknxt
  1599. Xgook:
  1600. X        or    ax,ax            ; end of list?
  1601. X        jnz    gookloop        ; around and around
  1602. X        ret
  1603. X
  1604. Xlargestmem    ENDP
  1605. X
  1606. X;-------------------------------------------------------------------------------
  1607. X
  1608. Xkillmem     PROC    NEAR
  1609. X
  1610. X        ASSUME    DS:NOTHING,ES:ovltbl
  1611. X
  1612. X        test    ds:memblkflg,MASK_used    ; is it used?
  1613. X        jz    memnotused        ; don't kill ovl
  1614. X        push    es
  1615. X        mov    es,ds:memblkovl
  1616. X        and    ovlflg,NOT MASK loaded    ; zap ovl associated with this blk
  1617. X        and    ovlflg,NOT MASK ems
  1618. X        pop    es
  1619. Xmemnotused:
  1620. X        jmp    mergemem        ; merge free memory
  1621. X
  1622. Xkillmem     ENDP
  1623. X
  1624. X;-------------------------------------------------------------------------------
  1625. X
  1626. Xkillovl     PROC    NEAR        ; preserves bx
  1627. X
  1628. X        ASSUME    DS:ovltbl,ES:NOTHING
  1629. X
  1630. X        mov    ds,ax
  1631. X        and    ovlflg,NOT MASK loaded    ; ovl no longer loaded
  1632. X        test    ovlflg,MASK ems     ; was it in ems ?
  1633. X        jz    noemskill
  1634. X        and    ovlflg,NOT MASK ems    ; no longer in ems
  1635. X        mov    ax,ovlemshdl
  1636. X        call    mappage
  1637. Xnoemskill:
  1638. X        mov    ax,ovlmemblk        ; get mem blk
  1639. X        sub    ax,MEMCTLBLKSIZ
  1640. X        mov    ds,ax
  1641. X        jmp    mergemem        ; merge free memory
  1642. X
  1643. Xkillovl     ENDP
  1644. X
  1645. X;-------------------------------------------------------------------------------
  1646. X
  1647. Xmergemem    PROC    NEAR
  1648. X
  1649. X; merge physically adjacent free memory blocks. Preserves es. ds -> a free block.
  1650. X
  1651. X        ASSUME    DS:NOTHING,ES:NOTHING
  1652. X
  1653. X        push    dx
  1654. X        push    es
  1655. X        and    ds:memblkflg,NOT MASK_used ; set current free
  1656. X        mov    ax,ds:memblkprv     ; get previous blk
  1657. X        or    ax,ax            ; was there a previous blk?
  1658. X        jz    gibber            ; nope
  1659. X        mov    es,ax
  1660. X        test    es:memblkflg,MASK_used    ; is the previous blk used?
  1661. X        jnz    gibber            ; yup
  1662. X        add    ax,es:memblksiz     ; end of previous blk
  1663. X        mov    dx,ds
  1664. X        cmp    dx,ax            ; physically adjacent?
  1665. X        jnz    gibber            ; nope
  1666. X        mov    ax,ds:memblksiz
  1667. X        add    es:memblksiz,ax     ; adjust size of new larger blk
  1668. X        mov    ax,ds:memblknxt     ; fix pointers
  1669. X        mov    es:memblknxt,ax
  1670. X        or    ax,ax
  1671. X        jz    almostgibber
  1672. X        mov    ds,ax            ; fix pointer of next blk
  1673. X        mov    ds:memblkprv,es
  1674. Xalmostgibber:
  1675. X        mov    ax,es
  1676. X        mov    ds,ax            ; new blk segment
  1677. Xgibber:
  1678. X        mov    ax,ds:memblknxt     ; get next blk
  1679. X        or    ax,ax            ; was there a next blk?
  1680. X        jz    killdone        ; nope
  1681. X        mov    es,ax
  1682. X        test    es:memblkflg,MASK_used    ; is the nxt blk used?
  1683. X        jnz    killdone        ; yup
  1684. X        mov    ax,ds
  1685. X        add    ax,ds:memblksiz     ; end of this blk
  1686. X        mov    dx,es
  1687. X        cmp    ax,dx            ; physically adjacent?
  1688. X        jnz    killdone        ; nope
  1689. X        mov    ax,es:memblksiz
  1690. X        add    ds:memblksiz,ax     ; adjust size of new larger blk
  1691. X        mov    ax,es:memblknxt     ; fix pointers
  1692. X        mov    ds:memblknxt,ax
  1693. X        or    ax,ax
  1694. X        jz    killdone
  1695. X        mov    es,ax            ; fix pointer of blk after nxt
  1696. X        mov    es:memblkprv,ds
  1697. Xkilldone:
  1698. X        and    ds:memblkflg,NOT MASK_used ; make sure it's free
  1699. X        pop    es
  1700. X        pop    dx
  1701. X        mov    ax,ds
  1702. X        ret
  1703. X
  1704. Xmergemem    ENDP
  1705. X
  1706. X;-------------------------------------------------------------------------------
  1707. X
  1708. Xgetmoreram    PROC    NEAR            ; try to alloc remaining pieces
  1709. X                        ; of memory if any
  1710. X        ASSUME    DS:NOTHING,ES:NOTHING    ; return dx = biggest block
  1711. X
  1712. X        push    cx
  1713. X        push    bx
  1714. X        push    si
  1715. X        push    di
  1716. X        push    ds
  1717. X        push    es
  1718. X        xor    dx,dx
  1719. X        mov    ax,memblk1st
  1720. Xnxtlowblk:
  1721. X        mov    ds,ax
  1722. X        mov    ax,ds:memblknxt
  1723. X        or    ax,ax
  1724. X        jnz    nxtlowblk
  1725. X
  1726. X        mov    si,OFFSET memblks    ; a place to store the handles
  1727. X        mov    di,OFFSET tempmem    ; a place to store the rejects
  1728. X        mov    cx,16            ; 16 more max
  1729. Xgetramlp:
  1730. X        mov    ah,DOSALLOC
  1731. X        mov    bx,0ffffh        ; Everything
  1732. X        int    DOS
  1733. X        cmp    bx,10h            ; nothing smaller than .25k please
  1734. X        jc    gotallram
  1735. X        mov    ah,DOSALLOC        ; allocate our own memory
  1736. X        int    DOS
  1737. X        jc    gotallram        ; oops!
  1738. X        cmp    ax,ovltblbse        ; is it after our first mem blk?
  1739. X        jc    releaseblk
  1740. X        cmp    dx,bx
  1741. X        jnc    notbigger
  1742. X        mov    dx,bx
  1743. Xnotbigger:
  1744. X        mov    cs:[si],ax        ; save it
  1745. X        mov    es,ax
  1746. X        mov    es:memblkflg,0        ; clear mem flags
  1747. X        mov    es:memblknxt,0        ; set next to nothing
  1748. X        mov    es:memblkovl,0        ; no overlays loaded
  1749. X        mov    es:memblkprv,ds     ; point to previous
  1750. X        mov    es:memblksiz,bx     ; allocated memory block size
  1751. X        mov    ds:memblknxt,es     ; point to next
  1752. X        add    si,2
  1753. X        mov    ds,ax
  1754. X        jmp    short getnxtram
  1755. Xreleaseblk:
  1756. X        mov    cs:[di],ax
  1757. X        add    di,2
  1758. Xgetnxtram:
  1759. X        loop    getramlp
  1760. Xgotallram:
  1761. X        mov    si,OFFSET tempmem
  1762. X        mov    cx,16
  1763. Xreleaselp:
  1764. X        mov    ax,cs:[si]
  1765. X        cmp    ax,-1
  1766. X        jz    relnext
  1767. X        mov    es,ax
  1768. X        mov    ah,DOSFREE
  1769. X        int    DOS
  1770. X        mov    WORD PTR cs:[si],-1
  1771. Xrelnext:
  1772. X        add    si,2
  1773. X        loop    releaselp
  1774. X        pop    es
  1775. X        pop    ds
  1776. X        pop    di
  1777. X        pop    si
  1778. X        pop    bx
  1779. X        pop    cx
  1780. X        ret
  1781. X
  1782. Xgetmoreram    ENDP
  1783. X
  1784. X;-------------------------------------------------------------------------------
  1785. X
  1786. Xgetemsmem    PROC    NEAR
  1787. X
  1788. X        ASSUME    DS:NOTHING,ES:ovltbl
  1789. X
  1790. X        xor    dx,dx            ; no ems memory
  1791. X        cmp    emmflg,-1
  1792. X        jz    testemsslots
  1793. X        ret
  1794. Xtestemsslots:
  1795. X        mov    curemshandle,-1
  1796. X        mov    di,OFFSET emsmemblks
  1797. X        mov    bx,cx
  1798. X        mov    cx,16
  1799. Xemsfreeslot:
  1800. X        mov    ax,cs:[di]
  1801. X        cmp    ax, -1
  1802. X        jz    gotemsslot
  1803. X        call    mappage
  1804. X        cmp    ax,bx
  1805. X        jnc    foundpage
  1806. X        add    di,2
  1807. X        loop    emsfreeslot
  1808. X        mov    cx,bx
  1809. X        xor    dx,dx
  1810. X        ret
  1811. Xgotemsslot:
  1812. X        mov    cx,bx
  1813. X        mov    bx,4
  1814. X        mov    ah,EMMALLOC
  1815. X        push    cx            ; paranoia ! shouldn't be necessary.
  1816. X        push    di
  1817. X        push    es
  1818. X        int    EMM
  1819. X        pop    es
  1820. X        pop    di
  1821. X        pop    cx
  1822. X        or    ah,ah
  1823. X        jz    gotsomeems
  1824. X        xor    dx,dx
  1825. X        ret
  1826. Xgotsomeems:
  1827. X        mov    cs:[di],dx
  1828. X        mov    ovlemshdl,dx
  1829. X        or    ovlflg,MASK ems
  1830. X        mov    ax,dx
  1831. X        call    mapemspages
  1832. X        mov    ax,emsframe
  1833. X        mov    ds,ax
  1834. X        mov    ds:memblkflg,0        ; clear mem flags
  1835. X        mov    ds:memblknxt,0        ; set next to nothing
  1836. X        mov    ds:memblkprv,0        ; set previous to nothing
  1837. X        mov    ds:memblkovl,0        ; no overlay loaded
  1838. X        mov    dx,1000h
  1839. X        mov    ds:memblksiz,dx
  1840. X        ret
  1841. X
  1842. Xfoundpage:
  1843. X        mov    cx,bx
  1844. X        mov    ds,si
  1845. X        mov    dx,ax
  1846. X        mov    ax,cs:[di]
  1847. X        mov    ovlemshdl,ax
  1848. X        or    ovlflg,MASK ems
  1849. X        ret
  1850. X
  1851. Xgetemsmem    ENDP
  1852. X
  1853. X;-------------------------------------------------------------------------------
  1854. X
  1855. Xmappage     PROC    NEAR            ; map a 64K block of EMS mem.
  1856. X
  1857. X        ASSUME    DS:NOTHING,ES:ovltbl
  1858. X
  1859. X        cmp    ax,curemshandle
  1860. X        jnz    doems
  1861. X        ret
  1862. Xdoems:
  1863. X        push    bx
  1864. X        push    dx
  1865. X        push    ds
  1866. X        push    es
  1867. X        call    mapemspages
  1868. X        mov    ax,emsframe
  1869. X        xor    dx,dx
  1870. X        xor    si,si
  1871. Xemsset:
  1872. X        mov    ds,ax
  1873. X        test    ds:memblkflg,MASK_used    ; mem blk used ?
  1874. X        jz    emsfreeblk
  1875. X        mov    es,ds:memblkovl
  1876. X        or    ovlflg,MASK ems OR MASK loaded
  1877. X        jmp    emsnext
  1878. Xemsfreeblk:
  1879. X        mov    ax,ds:memblksiz
  1880. X        cmp    dx,ax
  1881. X        jnc    emsnext
  1882. X        mov    dx,ax
  1883. X        mov    si,ds
  1884. Xemsnext:
  1885. X        mov    ax,ds:memblknxt
  1886. X        or    ax,ax
  1887. X        jnz    emsset
  1888. X
  1889. X        mov    ax,dx
  1890. X        pop    es
  1891. X        pop    ds
  1892. X        pop    dx
  1893. X        pop    bx
  1894. X        ret
  1895. X
  1896. Xmappage     ENDP
  1897. X
  1898. X;-------------------------------------------------------------------------------
  1899. X
  1900. Xmapemspages    PROC    NEAR
  1901. X
  1902. X        ASSUME    DS:NOTHING,ES:ovltbl
  1903. X
  1904. X        push    es
  1905. X        push    bx
  1906. X        push    cx
  1907. X        push    dx
  1908. X        mov    curemshandle,ax
  1909. X        mov    dx,ax
  1910. X        mov    ah,EMMMAP
  1911. X        xor    al,al            ; physical page 0
  1912. X        xor    bx,bx            ; logical page 0
  1913. X        push    dx
  1914. X        int    EMM
  1915. X        pop    dx
  1916. X        or    ah,ah
  1917. X        jnz    emmerror
  1918. X        mov    ah,EMMMAP
  1919. X        mov    al,1            ; physical page 1
  1920. X        mov    bx,1            ; logical page 1
  1921. X        push    dx
  1922. X        int    EMM
  1923. X        pop    dx
  1924. X        or    ah,ah
  1925. X        jnz    emmerror
  1926. X        mov    ah,EMMMAP
  1927. X        mov    al,2            ; physical page 2
  1928. X        mov    bx,2            ; logical page 2
  1929. X        push    dx
  1930. X        int    EMM
  1931. X        pop    dx
  1932. X        or    ah,ah
  1933. X        jnz    emmerror
  1934. X        mov    ah,EMMMAP
  1935. X        mov    al,3            ; physical page 3
  1936. X        mov    bx,3            ; logical page 3
  1937. X        int    EMM
  1938. X        or    ah,ah
  1939. X        jnz    emmerror
  1940. X        mov    es,ovltblbse
  1941. X        mov    cx,ovlcnt
  1942. X        xor    bx,bx
  1943. Xtestems:
  1944. X        test    ovlflg[bx],MASK ems
  1945. X        jz    nxttestems
  1946. X        and    ovlflg[bx],NOT MASK loaded
  1947. Xnxttestems:
  1948. X        add    bx,OVLSEGSIZ
  1949. X        loop    testems
  1950. X        pop    dx
  1951. X        pop    cx
  1952. X        pop    bx
  1953. X        pop    es
  1954. X        ret
  1955. X
  1956. Xemmerror:
  1957. X        mov    al,EMSERR        ; ems manager error
  1958. X        jmp    putserr
  1959. X
  1960. Xmapemspages    ENDP
  1961. X
  1962. X;-------------------------------------------------------------------------------
  1963. X
  1964. Xgethdr        PROC    NEAR            ; read EXE header from handle
  1965. X
  1966. X        ASSUME    DS:NOTHING,ES:NOTHING
  1967. X
  1968. X        push    cx
  1969. X        push    ds
  1970. X        mov    ax,cs
  1971. X        mov    ds,ax
  1972. X        mov    dx,OFFSET hdr        ; a place to put it
  1973. X        mov    bx,ovlexefilhdl     ; the file handle
  1974. X        mov    cx,TYPE EXEHDR        ; header size in bytes
  1975. X        mov    ah,DOSREAD
  1976. X        int    DOS            ; read from file
  1977. X        jc    exegone         ; oops
  1978. X        cmp    ax,cx            ; got correct number of bytes?
  1979. X        jnz    exegone         ; nope
  1980. X        pop    ds
  1981. X        pop    cx
  1982. X        ret                ; Wow, it worked!
  1983. Xexegone:
  1984. X        mov    al,HDRERR        ; You lose!
  1985. X        jmp    putserr
  1986. X
  1987. Xgethdr        ENDP
  1988. X
  1989. X;-------------------------------------------------------------------------------
  1990. X
  1991. Xputserr     PROC    NEAR
  1992. X
  1993. X; display error msg, close file, restore int vectors, free mem and return to DOS.
  1994. X
  1995. X        ASSUME    DS:NOTHING,ES:NOTHING
  1996. X
  1997. X        xor    ah,ah
  1998. X        push    ax            ; keep return code for later
  1999. X        push    cs
  2000. X        pop    ds
  2001. X        mov    bx,ax
  2002. X        shl    bx,1
  2003. X        add    bx,OFFSET errortbl
  2004. X        mov    dx,[bx]
  2005. X        cmp    dx,-1
  2006. X        jz    freeints
  2007. X        push    dx
  2008. X        mov    dx,OFFSET msghead
  2009. X        mov    ah,PRINT
  2010. X        int    DOS
  2011. X        pop    dx
  2012. X        mov    ah,PRINT
  2013. X        int    DOS            ; display error msg
  2014. X
  2015. X        mov    ah,PRINT
  2016. X        mov    dx,OFFSET diag
  2017. X        int    DOS
  2018. X        pop    ax
  2019. X        push    ax
  2020. X        call    itoa            ; error number
  2021. X        mov    ah,DOSPUTC
  2022. X        mov    dl,':'
  2023. X        int    DOS
  2024. X        mov    ax,VERSION
  2025. X        call    itoa            ; version number
  2026. X        mov    ah,DOSPUTC
  2027. X        mov    dl,':'
  2028. X        int    DOS
  2029. X        mov    ax,0a000h
  2030. X        sub    ax,ovltblbse        ; conventional memory
  2031. X        call    itoa
  2032. X        mov    ah,DOSPUTC
  2033. X        mov    dl,':'
  2034. X        int    DOS
  2035. X        mov    si,OFFSET emsmemblks
  2036. X        mov    cx,16
  2037. X        xor    ax,ax
  2038. Xemstotlp:
  2039. X        cmp    WORD PTR cs:[si],-1
  2040. X        jz    gotemstot
  2041. X        add    ax,emmframesiz
  2042. X        add    si,2
  2043. X        loop    emstotlp
  2044. Xgotemstot:
  2045. X        call    itoa            ; ems usage in blocks
  2046. X        mov    ah,DOSPUTC
  2047. X        mov    dl,')'
  2048. X        int    DOS
  2049. X
  2050. X        mov    dx,OFFSET msgtail
  2051. X        mov    ah,PRINT
  2052. X        int    DOS
  2053. Xfreeints:
  2054. X        call    rstvectors        ; restore all int vectors
  2055. X
  2056. X        mov    ax,ovltblbse
  2057. X        cmp    ax,-1
  2058. X        jz    freememblks
  2059. X        mov    es,ax
  2060. X        mov    ah,DOSFREE
  2061. X        int    DOS
  2062. Xfreememblks:
  2063. X        mov    cx,16            ; do all allocated mem blocks
  2064. X        mov    si,OFFSET memblks
  2065. Xfreememlp:
  2066. X        mov    ax,cs:[si]        ; get memory blk segment
  2067. X        cmp    ax,-1            ; was one ever allocated?
  2068. X        jz    nxtmemlp        ; nope
  2069. X        mov    es,ax
  2070. X        mov    ah,DOSFREE        ; must free it.
  2071. X        int    DOS
  2072. Xnxtmemlp:
  2073. X        add    si,2
  2074. X        loop    freememlp
  2075. X        mov    cx,16            ; do all allocated ems blocks
  2076. X        mov    si,OFFSET emsmemblks
  2077. Xfreeemsmemlp:
  2078. X        mov    dx,cs:[si]        ; get memory blk segment
  2079. X        cmp    dx,-1            ; was one ever allocated?
  2080. X        jz    nxtemsmemlp        ; nope
  2081. X        mov    ah,EMMFREE        ; must free it.
  2082. X        int    EMM
  2083. Xnxtemsmemlp:
  2084. X        add    si,2
  2085. X        loop    freeemsmemlp
  2086. Xclosefile:
  2087. X        mov    bx,ovlexefilhdl     ; get file handle
  2088. X        cmp    bx,-1            ; was the file ever opened?
  2089. X        jz    byebye            ; nope
  2090. X        mov    ah,DOSCLOSE        ; close it
  2091. X        int    DOS
  2092. Xbyebye:
  2093. X        pop    ax            ; return code in al
  2094. X        mov    ah,TERMINATE
  2095. X        int    DOS            ; terminate this process
  2096. X
  2097. Xputserr     ENDP
  2098. X
  2099. X;-------------------------------------------------------------------------------
  2100. X
  2101. Xitoa        PROC    NEAR
  2102. X
  2103. X        push    ax
  2104. X        xchg    ah,al
  2105. X        call    putbyte
  2106. X        pop    ax
  2107. X        jmp    putbyte
  2108. X
  2109. Xitoa        ENDP
  2110. X
  2111. X;-------------------------------------------------------------------------------
  2112. X
  2113. Xputbyte     PROC    NEAR
  2114. X
  2115. X        push    ax
  2116. X        shr    al,1
  2117. X        shr    al,1
  2118. X        shr    al,1
  2119. X        shr    al,1
  2120. X        call    nibble
  2121. X        pop    ax
  2122. X        jmp    nibble
  2123. X
  2124. Xputbyte     ENDP
  2125. X
  2126. X;-------------------------------------------------------------------------------
  2127. X
  2128. Xnibble        PROC    NEAR
  2129. X
  2130. X        and    al,0fh
  2131. X        add    al,30h
  2132. X        cmp    al,3ah
  2133. X        jc    nibok
  2134. X        add    al,7
  2135. Xnibok:
  2136. X        mov    dl,al
  2137. X        mov    ah,DOSPUTC
  2138. X        int    DOS
  2139. X        ret
  2140. X
  2141. Xnibble        ENDP
  2142. X
  2143. X;-------------------------------------------------------------------------------
  2144. X
  2145. Xsetvectors    PROC    NEAR
  2146. X
  2147. X        push    ds
  2148. X        xor    ax,ax
  2149. X        mov    ds,ax
  2150. X        mov    si,cs:intnum
  2151. X        cli
  2152. X        mov    ax,[si]
  2153. X        mov    WORD PTR cs:oldvec,ax    ; save original vector
  2154. X        mov    ax,[si+2]
  2155. X        mov    WORD PTR cs:oldvec+2,ax
  2156. X        mov    ax,OFFSET ovlmgr    ; point to ovlmgr
  2157. X        mov    [si],ax         ; set int vector
  2158. X        mov    [si+2],cs
  2159. X
  2160. X        mov    si,DOS*4
  2161. X        mov    ax,[si]
  2162. X        mov    WORD PTR cs:oldint21,ax ; save original vector
  2163. X        mov    ax,[si+2]
  2164. X        mov    WORD PTR cs:oldint21+2,ax
  2165. X        mov    ax,OFFSET int21     ; point to new int21
  2166. X        mov    [si],ax         ; set int vector
  2167. X        mov    [si+2],cs
  2168. X        sti
  2169. X        pop    ds
  2170. X        ret
  2171. X
  2172. Xsetvectors    ENDP
  2173. X
  2174. X;-------------------------------------------------------------------------------
  2175. X
  2176. Xrstvectors    PROC    NEAR
  2177. X
  2178. X        push    ds
  2179. X        xor    ax,ax
  2180. X        mov    ds,ax
  2181. X        mov    si,DOS*4
  2182. X        cli
  2183. X        mov    ax,WORD PTR cs:oldint21 ; put back dos vector
  2184. X        cmp    ax,-1
  2185. X        jz    rstvec
  2186. X        mov    [si],ax
  2187. X        mov    ax,WORD PTR cs:oldint21+2
  2188. X        mov    [si+2],ax
  2189. Xrstvec:
  2190. X        mov    si,cs:intnum
  2191. X        mov    ax,WORD PTR cs:oldvec    ; put back ovlmgr vector
  2192. X        cmp    ax,-1
  2193. X        jz    rstdone
  2194. X        mov    [si],ax
  2195. X        mov    ax,WORD PTR cs:oldvec+2
  2196. X        mov    [si+2],ax
  2197. X        sti
  2198. Xrstdone:
  2199. X        pop    ds
  2200. X        ret
  2201. X
  2202. Xrstvectors    ENDP
  2203. X
  2204. Xcode        ENDS
  2205. X
  2206. X        END
  2207. END_OF_FILE
  2208. if test 40486 -ne `wc -c <'others/ovlmgr.asm'`; then
  2209.     echo shar: \"'others/ovlmgr.asm'\" unpacked with wrong size!
  2210. fi
  2211. # end of 'others/ovlmgr.asm'
  2212. echo shar: Extracting \"'vms/vmsmisc.c'\" \(386 characters\)
  2213. sed "s/^X//" >'vms/vmsmisc.c' <<'END_OF_FILE'
  2214. X/*    SCCS Id: @(#)vmsmisc.c    3.0    90/22/02
  2215. X/* NetHack may be freely redistributed.  See license for details. */
  2216. X
  2217. X#include <ssdef.h>
  2218. X#include <stsdef.h>
  2219. X
  2220. Xvoid
  2221. Xvms_exit(status)
  2222. Xint status;
  2223. X{
  2224. X    exit(status ? (SS$_ABORT | STS$M_INHIB_MSG) : SS$_NORMAL);
  2225. X}
  2226. X
  2227. Xvoid
  2228. Xvms_abort()
  2229. X{
  2230. X    (void) LIB$SIGNAL(SS$_DEBUG);
  2231. X}
  2232. X
  2233. X#ifdef VERYOLD_VMS
  2234. X#include "oldcrtl.c"        /* "[-.vms]oldcrtl.c" */
  2235. X#endif
  2236. END_OF_FILE
  2237. if test 386 -ne `wc -c <'vms/vmsmisc.c'`; then
  2238.     echo shar: \"'vms/vmsmisc.c'\" unpacked with wrong size!
  2239. fi
  2240. # end of 'vms/vmsmisc.c'
  2241. echo shar: End of archive 20 \(of 24\).
  2242. cp /dev/null ark20isdone
  2243. MISSING=""
  2244. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ; do
  2245.     if test ! -f ark${I}isdone ; then
  2246.     MISSING="${MISSING} ${I}"
  2247.     fi
  2248. done
  2249. if test "${MISSING}" = "" ; then
  2250.     echo You have unpacked all 24 archives.
  2251.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2252. else
  2253.     echo You still need to unpack the following archives:
  2254.     echo "        " ${MISSING}
  2255. fi
  2256. ##  End of shell archive.
  2257. exit 0
  2258.